home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / c / vbcc / machines / amiga68k / libsrc / stdlib / malloc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-08  |  3.0 KB  |  116 lines

  1. #include <stdlib.h>
  2.  
  3. /*#include <exec/memory.h>*/
  4.  
  5.  
  6. /*  stark modifizierte Version aus K&R  */
  7.  
  8. static union _mheader _base;
  9. static union _mheader *_freep=0;
  10.  
  11. size_t _nalloc=1023;
  12. union _mheader *_first_mlist=0,*_last_mlist=0;
  13.  
  14. union _mheader *_morecore(size_t anu)
  15. {
  16.     union _mheader *up;size_t nu;
  17.     if(anu<_nalloc) nu=_nalloc; else nu=anu;
  18.     up=(union _mheader *)AllocMem((nu+1)*sizeof(union _mheader),0L);
  19.     if(!up) return(0);
  20.     up->s.size=nu+1; up->s.ptr=0; /*  Merken fuer Freigabe am Schluss */
  21.     if(_last_mlist){
  22.         _last_mlist->s.ptr=up;_last_mlist=up;
  23.     }else{
  24.         _last_mlist=_first_mlist=up;
  25.     }
  26.     up++;
  27.     up->s.size=nu;
  28.     if(anu>_nalloc) return((void *)up);
  29.     free((void *)(up+1));
  30.     return(_freep);
  31. }
  32. void _freemem(void)
  33. /*  Gibt allen Speicher frei    */
  34. {
  35.     union _mheader *p=_first_mlist,*m;
  36.     while(p){
  37.         m=p->s.ptr;
  38.         FreeMem(p,p->s.size*sizeof(union _mheader));
  39.         p=m;
  40.     }
  41. }
  42. void *malloc(size_t nbytes)
  43. {
  44.     union _mheader *p,*prevp;
  45.     size_t nunits;
  46.     /*  aufrunden   */
  47.     nunits=(nbytes+sizeof(union _mheader)-1)/sizeof(union _mheader)+1;
  48.     if(nunits>_nalloc){
  49.         if(!(p=_morecore(nunits))) return(0);
  50.         p->s.size=nunits;p->s.ptr=0;
  51.         return(p+1);
  52.     }
  53.     if((prevp=_freep)==0){   /*  noch keine base */
  54.         _base.s.ptr=_freep=prevp=&_base;
  55.         _base.s.size=0;
  56.     }
  57.     for(p=prevp->s.ptr;;prevp=p,p=p->s.ptr){
  58.         if(p->s.size>=nunits){  /*  Block passt */
  59.             if(p->s.size==nunits){  /*  genau   */
  60.                 prevp->s.ptr=p->s.ptr;
  61.             }else{  /*  ist kleiner */
  62.                 p->s.size-=nunits;p+=p->s.size;p->s.size=nunits;
  63.             }
  64.             _freep=prevp;
  65.             return((void *)(p+1));
  66.         }
  67.         /*  mehr Speicher anfordern     */
  68.         if(p==_freep) if(!(p=_morecore(nunits))) return(0);
  69.     }
  70. }
  71. void free(void *ap)
  72. {
  73.     union _mheader *bp,*p,*last;
  74.     bp=(union _mheader *)ap;
  75.     if(!bp) return;
  76.     bp--;
  77.     if(bp->s.size>_nalloc){
  78.     /*  grosse Bloecke gleich freigeben     */
  79.         bp--;   /*  Startadresse der mlist  */
  80.         p=_first_mlist;
  81. /*        printf("bp=%p\n",bp);*/
  82.         while(p){
  83. /*            printf("p=%p\n",p);*/
  84.             if(p==bp){  /*  Block gefunden  */
  85.                 if(p==_first_mlist) _first_mlist=p->s.ptr;
  86.                     else last->s.ptr=p->s.ptr;
  87.                 if(p==_last_mlist) _last_mlist=last;
  88.                 FreeMem(p,p->s.size*sizeof(union _mheader));
  89.                 return;
  90.             }
  91.             last=p;p=p->s.ptr;
  92.         }
  93.         /*  wenn man hierherkommt, koennte man einen Fehler melden  */
  94.         Write(Output(),"memory list corrupt!\n",21);
  95.         return;
  96.     }
  97.     for(p=_freep;!(bp>p&&bp<p->s.ptr);p=p->s.ptr)
  98.         if(p>=p->s.ptr&&(bp>p||bp<p->s.ptr))
  99.             break;
  100.  
  101.     if(bp+bp->s.size==p->s.ptr){
  102.         bp->s.size+=p->s.ptr->s.size;
  103.         bp->s.ptr=p->s.ptr->s.ptr;
  104.     }else{
  105.         bp->s.ptr=p->s.ptr;
  106.     }
  107.     if(p+p->s.size==bp){
  108.         p->s.size+=bp->s.size;
  109.         p->s.ptr=bp->s.ptr;
  110.     }else{
  111.         p->s.ptr=bp;
  112.     }
  113.     _freep=p;
  114. }
  115.  
  116.